package Model;

import java.sql.Connection;
//import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//import java.sql.Statement;
//import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collection;
//import java.util.Collections;
//import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.sql.DataSource;

/**
 *
 * @author pyty
 */
public class BorrowManagerImpl implements BorrowManager {

    private static final Logger logger = Logger.getLogger(
            MediumManagerImpl.class.getName());

    private DataSource ds = null;

    private ClientManager clientManager = new ClientManagerImpl();
    private MediumManager mediumManager = new MediumManagerImpl();


    void setDataSource (DataSource ds) {
        this.ds = ds;
    }

    public void borrowMedium(Client client, Medium medium) {
        if (medium == null || medium.getId() == null) {
            throw new IllegalArgumentException("medium");
        }
        if (client == null || client.getId() == null) {
            throw new IllegalArgumentException("client");
        }

        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = ds.getConnection();

            st = conn.prepareStatement("SELECT CLIENT_ID FROM medium WHERE id=?");
            st.setLong(1, medium.getId());

            ResultSet rs = st.executeQuery();
            Long customerId = null;

           if (rs.next()) {
                customerId = rs.getLong("CLIENT_ID");
                assert !rs.next();
            } else {
                throw new IllegalArgumentException("Medium with id " + medium.getId() + " doesnt exists.");
            }

            if (customerId != 0) {
                throw new IllegalArgumentException("Medium already borrowed.");
            }

            st = conn.prepareStatement(
                    "UPDATE medium SET client_id = ? WHERE id = ?");
            st.setLong(1, client.getId());
            st.setLong(2, medium.getId());

            int count = st.executeUpdate();
            assert count == 1;  

        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error when inserting medium into DB", ex);
            throw new RuntimeException("Error when inserting medium into DB", ex);
        } finally {
            DBUtils.closeQuietly(conn);
        }

    }

    //------------------------------ klienta tu nepotrebujeme
    public void returnBorrow(Client client, Medium medium) {
        if (medium == null || medium.getId() == null) {
            throw new IllegalArgumentException("medium");
        }
        if (client == null || client.getId() == null) {
            throw new IllegalArgumentException("client");
        }

        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = ds.getConnection();

            st = conn.prepareStatement("SELECT client_id FROM medium WHERE id=?");
            st.setLong(1, medium.getId());

            ResultSet rs = st.executeQuery();
            Long customerId = null;

            if (rs.next()) {
                customerId = rs.getLong("client_id");
                assert !rs.next();
            } else {
                throw new IllegalArgumentException("Medium with id " + medium.getId() + " doesnt exists.");
            }

            if (customerId == 0) {
                throw new IllegalArgumentException("Medium not borrowed.");
            }

            st = conn.prepareStatement(
                    "UPDATE medium SET client_id = ? WHERE id = ?");
            st.setLong(1, 0);
            st.setLong(2, medium.getId());
            int count = st.executeUpdate();
            assert count == 1;

        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error when inserting medium into DB", ex);
            throw new RuntimeException("Error when inserting medium into DB", ex);
        } finally {
            DBUtils.closeQuietly(conn);
        }
    }

    public Client findClientWithMedium(Medium medium) {
        if (medium == null || medium.getId() == null) {
            throw new IllegalArgumentException("Invalid medium");
        }

        Client client = new Client();
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = ds.getConnection();

            st = conn.prepareStatement("SELECT client_id FROM medium WHERE id=?");
            st.setLong(1, medium.getId());

            ResultSet rs = st.executeQuery();
            Long customerId = null;

            if (rs.next()) {
                customerId = rs.getLong("client_id");
                assert !rs.next();
            } else {
                throw new IllegalArgumentException("Medium with id " + medium.getId() + " doesnt exists.");
            }

            if (customerId == 0) {
                throw new IllegalArgumentException("Medium not borrowed.");
            }

            st = conn.prepareStatement(
                    "SELECT * FROM clients WHERE id = ?");
            st.setLong(1, customerId);

            rs = st.executeQuery();

            if (rs.next()) {
                client.setId(rs.getLong("id"));
                client.setName(rs.getString("clientsName"));
                client.setGoldMember(rs.getString("goldMember"));
                client.setBlackListed(rs.getString("blackListed"));
                client.setRegistrationDate(rs.getDate("registrationDate"));


                assert !rs.next();
            } else {
                throw new IllegalArgumentException("Client with id " + customerId + " doesnt exists.");
            }

            return client;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error when inserting medium into DB", ex);
            throw new RuntimeException("Error when inserting medium into DB", ex);
        } finally {
            DBUtils.closeQuietly(conn);
        }
    }

    public Collection<Medium> getMediumsBorrovedByClient(Client client) {
        if (client == null || client.getId() == null) {
            throw new IllegalArgumentException("Invalid medium");
        }

        List<Medium> mediums = new ArrayList<Medium>();
        // Medium medium = new Medium();

        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = ds.getConnection();

            st = conn.prepareStatement(
                    "SELECT id, name, author, type, description"
                  + " FROM medium WHERE client_id = ?");
            st.setLong(1, client.getId());

            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                Medium result = new Medium();
                result.setId(rs.getLong("id"));
                result.setName(rs.getString("name"));
                result.setAuthor(rs.getString("author"));
                result.setType(rs.getString("type"));
                result.setDescription(rs.getString("description"));
                mediums.add(result);
            }
        
            return mediums;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error when inserting medium into DB", ex);
            throw new RuntimeException("Error when inserting medium into DB", ex);
        } finally {
            DBUtils.closeQuietly(conn);
        }
    }

}

